//
//  File.swift
//
//
//  Created by didi on 2022/9/8.
//

import MolecularObjects
import Vapor

struct SystemApiErrorMiddleware: AsyncMiddleware {
    func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response {
        do {
            return try await next.respond(to: request)
        } catch {
            let status: HTTPResponseStatus
            let headers: HTTPHeaders
            let message: String
            let details: [ErrorDetail]

            switch error {
            case let abort as ValidationAbort:
                status = abort.abort.status
                headers = abort.abort.headers
                message = abort.message ?? abort.reason
                details = abort.details
            case let abort as Abort:
                status = abort.status
                headers = abort.headers
                message = abort.reason
                details = []
            default:
                status = .internalServerError
                headers = [:]
                message = request.application.environment.isRelease ? "Something went wrong." : error.localizedDescription
                details = []
            }

            request.logger.report(error: error)

            let response = Response(status: status, headers: headers)
            do {
                response.body = try .init(data: JSONEncoder().encode(MError(message: message, details: details)))
                response.headers.replaceOrAdd(name: .contentType, value: "application/json; charset=utf-8")
            } catch {
                response.body = .init(string: "Oops: \(error)")
                response.headers.replaceOrAdd(name: .contentType, value: "text/plain; charset=utf-8")
            }

            return response
        }
    }
}
